using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mail;
using System.Threading;
using Syno.Core.Output;
using Syno.Core.Output.DataDisplay;
using Syno.Core.Output.DataLoader;
using Syno.Core.Output.OutputFormat;
using Syno.Core.Xml.Data;

namespace Syno.Core.Xml
{
    public class SynoConfigProcessor
    {
        public void Run(SynoConfig synoConfig, string profile)
        {
            if (synoConfig.Profile.ContainsKey(profile))
            {
                Run(synoConfig, synoConfig.Profile[profile]);
            }
            else
            {
                throw new Exception(string.Format("Could not load profile [{0}] from list of profiles [{1}]", profile, string.Join(",",synoConfig.Profile.Keys.ToArray())));
            }
        }

        private void Run(SynoConfig synoConfig, Profile profile)
        {
            OutputManager outputManager = GetOutputManager(profile, synoConfig);
            outputManager.ProcessAll();
        }

        private OutputManager GetOutputManager(Profile profile, SynoConfig synoConfig)
        {
            var outputManager = new Output.OutputManager();
            foreach (var dataLoader in profile.DataLoaders)
            {
                DataHolder dataHolder;
                IDatabase dataSource;
                try
                {
                    dataHolder = synoConfig.DataHolders[dataLoader.Key];
                    
                }
                catch (Exception e)
                {
                    throw new Exception(string.Format("Could not add dataloader [{0}]", dataLoader.Key), e);
                }
                try
                {
                    dataSource = synoConfig.DataSource[dataLoader.Value];
                    
                }
                catch (Exception e)
                {
                    throw new Exception(string.Format("Could not add dataSource [{0}]", dataLoader.Value), e);
                }
                var sqlDataLoader = dataHolder.DataLoader as SqlDataLoader;
                if (sqlDataLoader != null)
                {
                    sqlDataLoader.Connection = dataSource;
                }

                outputManager.AddDataHolder(dataHolder);
            }
            var output = profile.Output as EmailFormatOutput;
            if (output != null)
            {
                output.Smtp = new SmtpClient();
            }
            outputManager.AddParameters(new Dictionary<string, string>() { 
            {"LongDateString", DateTime.Now.ToLongDateString()}, 
            {"ShortDateString", DateTime.Now.ToShortDateString()}, 
            {"ShortTimeString", DateTime.Now.ToShortTimeString()}, 
            {"LongTimeString", DateTime.Now.ToLongTimeString()}, 
            {"DateTime", DateTime.Now.ToString()}, 
            {"Profile", profile.Name}, 
            });
            outputManager.AddParameters(synoConfig.Parameters);
            outputManager.AddParameters(profile.Parameters);
            
            outputManager.AddOutput(profile.Output);
            return outputManager;
        }
    }
}